package com.panopset.gui;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;

import javax.swing.JPanel;

/**
 *  Off-screen graphic world, (Osgw in Java), term borrowed from my days at Apple, this does
 *  essentially the same thing, provide a flicker free place to do animation.
 *
 *  See TestOsgw to see a simple example of how to use it.
 *
 * @author Karl Dinwiddie
 *
 */
public abstract class Osgw {
    private final int w;
    private final int h;
    private int sleepCycle = 60;
    private static boolean isActive = true;

    /**
     * Stop all Osgw animation threads.
     */
    public static void close() {
        isActive = false;
    }

    public static boolean isActive() {
        return isActive;
    }

    public abstract void paintCycle(Graphics2D g);

    public Osgw(int width, int height) {
        this.w = width;
        this.h = height;
    }

    public Osgw(Dimension dim) {
        this(dim.width, dim.height);
    }

    /**
     * Set the time to sleep between refresh cycles in milliseconds, default is 60.
     * @param value in millis.
     */
    public void setSleepCycle(int value) {
        this.sleepCycle = value;
    }

    /**
     * Panel that contains the animation.
     * @return
     */
    public JPanel getPanel() {
        if (panel == null) {
            panel = new OSGWPanel();
            panel.setPreferredSize(new Dimension(w,h));
        }
        return panel;
    }
    JPanel panel;
    Image image;

    class OSGWPanel extends JPanel {

        @Override
        public void paint(Graphics g) {
            if (image == null) {
                super.paint(g);
                image = panel.createImage(w,h);
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        while (isActive()) {
                            paintCycle((Graphics2D) image.getGraphics());
                            panel.repaint();
                            try {
                                Thread.sleep(sleepCycle);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }

                }, "Graphix").start();
            } else {
                g.drawImage(image, 0, 0, null);
            }
        }
        private static final long serialVersionUID = 1L;
    }
}
